﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MvvmBindingPack;
using System.Runtime;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace WpfDemoAutoWire.ViewModels
{

    [ViewModelClassAlias("WindowAutoBindView")]
    [ViewModelClassAlias("WindowAutoBindViewModel")]
    [ViewModelClassAlias("WindowAutoBindViewModelSubMath")]
    [ViewModelClassAlias("WindowListboxSubMath")]
    [ViewModelClassAlias("WindowBindView")]
    [ViewModelClassAlias("WindowMainView")]
    public class WindowAutoBind : NotifyChangesBase
    {
        //=================================================================================================//
        string _textAndMsgLabelTxtA = "Content was binded - A";
        string _textAndMsgLabelTxtB = "Content was binded - B";
        //string _textAndMsgLabelTxtC = "Content was binded - C";
        string _textAndMsgLabelTxtD = "Content was binded - D";
        string _textAndMsgLabelTxtF = "Content was binded - F";
        int _widthF = 160;
        //=================================================================================================//


        //=================================================================================================//
        // Examples of declaration of auto wiring for properties & events in view model
        //=================================================================================================//

        /*A*/
        public string LabelXNameA_Content
        {
            get { return _textAndMsgLabelTxtA; }
            set { _textAndMsgLabelTxtA = value; NotifyPropertyChanged(); }
        }
        public int LabelXNameA_Width
        {
            get { return 160; }
            set { _widthF = value; NotifyPropertyChanged(); }
        }
        private void LabelXNameA_Loaded(object sender, RoutedEventArgs e)
        {
            LabelXNameA_Content = LabelXNameA_Content + "-Loaded";
        }

        /*B*/
        [ViewTarget("Content")]
        public string LabelXNameB
        {
            get { return _textAndMsgLabelTxtB; }
            set { _textAndMsgLabelTxtB = value; NotifyPropertyChanged(); }
        }
        [ViewTarget("Loaded")]
        private void LabelXNameB_badTag(object sender, RoutedEventArgs e)
        {
            LabelXNameB = LabelXNameB + "-Loaded";
        }

        /*C*/
        [ViewXNameAlias("LabelXNameC", "Content")]
        string _textAndMsgLabelTxtC = "Content was binded - C";


        /*D*/
        [ViewXNameAlias("LabelXNameD", "Content")]
        public string BadLabelXNameD
        {
            get { return _textAndMsgLabelTxtD; }
            set { _textAndMsgLabelTxtD = value; NotifyPropertyChanged(); }
        }
        [ViewXNameAlias("LabelXNameD", "Loaded")]
        private void BadLabelXNameDE(object sender, RoutedEventArgs e)
        {
            BadLabelXNameD = BadLabelXNameD + "-Loaded";
        }

        /*F*/
        [ViewXNameAlias("LabelXNameF", "Content", ValidatesOnNotifyDataErrors = true)]
        public string BadLabelXNameD1
        {
            get { return _textAndMsgLabelTxtF; }
            set { _textAndMsgLabelTxtF = value; NotifyPropertyChanged(); }
        }


        [ViewXNameAlias("LabelXNameF", "Width")]
        public int BadLabelXNameD2
        {
            get { return _widthF; }
            set { _widthF = value; NotifyPropertyChanged(); }
        }
        [ViewXNameAlias("LabelXNameF", "Loaded")]
        private void BadLabelXNameFE(object sender, RoutedEventArgs e)
        {
            BadLabelXNameD1 = BadLabelXNameD1 + "-Loaded";
        }

        //=================================================================================================//
        // Examples of declaration for auto wiring of command property in view model
        //=================================================================================================//

        /*A*/
        [ViewXNameAlias("ButtonXNameA", "Command.Execute")]
        public void ButtonXNameAExecute(object obj)
        {
            LabelXNameA_Content = "ButtonXNameA pressed";
        }
        [ViewXNameAlias("ButtonXNameA", "Command.CanExecute")]
        public bool ButtonXNameACanExecute(object obj)
        {
            return true;
        }
        public string ButtonXNameA_Content
        {
            get { return "ButtonXNameA"; }
        }

        /*B*/
        [ViewXNameAlias("ButtonXNameB", "Command.Execute")]
        private void ButtonXNameBExecute(object obj)
        {
            LabelXNameA_Content = "ButtonXNameB pressed";
        }
        [ViewXNameAlias("ButtonXNameB", "Command.CanExecute")]
        private bool ButtonXNameBCanExecute
        {
            get { return true; }
        }
        [ViewTarget("Content")]
        public string ButtonXNameB
        {
            get { return "ButtonXNameB"; }
        }

        /*C*/
        [ViewXNameAlias("ButtonXNameC", "Command.Execute")]
        public void ButtonXNameCExecute(object obj)
        {
            LabelXNameA_Content = "ButtonXNameC pressed";
        }
        [ViewXNameAlias("ButtonXNameC", "Command.CanExecute")]
        public bool ButtonXNameCCanExecute
        {
            get { return true; }
        }
        [ViewTarget("Content")]
        public string ButtonXNameC
        {
            get { return "ButtonXNameC"; }
        }


        //=================================================================================================//
        // Examples of using BindCommand together
        //=================================================================================================//
        public void ExecuteButtonBindCommand(object obj)
        {
            LabelXNameA_Content = "ButtonBindCommand pressed";
            var err = GetErrors("BadLabelXNameD1");
            if(err.GetEnumerator().MoveNext() == false)
            {
                InValidProperty("BadLabelXNameD1",true,"Set property to invalid");
                BadLabelXNameD1 = "Mark as invalid";
            }
            else
            {
                ValidProperty("BadLabelXNameD1", true);
                BadLabelXNameD1 = "Mark as valid";
            }
        }
        public bool CanExecuteButtonBindCommand
        {
            get { return true; }
        }

        //=================================================================================================//
        // Wire to the attached property
        //=================================================================================================//
        [ViewTarget("Grid.Row")]
        public int LabelXNameAP
        {
            get { return 10000; }
        }


        //=================================================================================================//
        //=================================================================================================//
        //=================================================================================================//
        // Wire to a View from the View Model
        //=================================================================================================//

        [ViewXNameAlias("ButtonXNameVM2M", "Command.Execute")]
        public void LabelXNameVM2MExecute(object obj)
        {
            LabelXNameA_Content = "ButtonXNameVM2M pressed";
            Label label = _LabelXNameVM2M as Label;
            if (label != null)
            {
                label.Content = "VM =>V.Label";
                if (_LabelXNameVM2MContent != null)
                {
                    string cont = (string)_LabelXNameVM2MContent.GetPropertyValue();
                    cont = cont + "| V.Label.Context";
                    _LabelXNameVM2MContent.SetPropertyValue(cont);

                    Button button = _ButtonXNameVM2M as Button;
                    if (button != null)
                    {
                        button.Content = ButtonXNameVM2M + "- link from View";
                        cont = cont + "|" + ButtonXNameVM2M;
                        _LabelXNameVM2MContent.SetPropertyValue(cont);

                    }
                    if (_ButtonXNameVM2MClick != null)
                    {
                        RoutedEventHandler Click = ButtonXNameVM2MClk;
                        _ButtonXNameVM2MClick.RemoveEventHandler(Click);
                        _ButtonXNameVM2MClick.AddEventHandler(Click);
                    }
                }

            }
        }

        [ViewXNameAlias("ButtonXNameVM2M", "Command.CanExecute")]
        public bool LabelXNameVM2MCanExecute
        {
            get { return true; }
        }
        [ViewTarget("Content")]
        public string ButtonXNameVM2M
        {
            get { return "ButtonXNameVM2M"; }
        }

        public void ButtonXNameVM2MClk(object sender, RoutedEventArgs e)
        {
            LabelXNameB = "ButtonXNameVM2M - Click setup from VM";
        }

        [ViewXNameSourceObjectMapping("LabelXNameVM2M")]
        private Label _LabelXNameVM2M;

        [ViewXNameSourceTargetMapping("LabelXNameVM2M", "Content")]
        private ViewXNameSourceTarget _LabelXNameVM2MContent;

        [ViewXNameSourceObjectMapping("ButtonXNameVM2M")]
        private Button _ButtonXNameVM2M;

        [ViewXNameSourceTargetMapping("ButtonXNameVM2M", "Click")]
        private ViewXNameSourceTarget _ButtonXNameVM2MClick;

    }
}

